﻿using Castle.Core.Configuration;
using Castle.Facilities.NHibernateIntegration;
using Inovout.Descriptors;
using Inovout.Runtime;
using NHibernate.Cfg;
using NHibernate.Connection;
using NHibernate.Dialect;
using NHibernate.Driver;
using System;

namespace Inovout.Repositories
{
    public class DatabaseConfigurationBuilder : IConfigurationBuilder
    {
        private const string connectionStringKey = "connectionString";
        private const string databaseTypeKey = "databaseType";

        public Configuration GetConfiguration(IConfiguration config)
        {
            
            NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();
            cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionProvider, typeof(DriverConnectionProvider).FullName);// "NHibernate.Driver.SqlClientDriver";
            cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionDriver, GetDriver(config));// "NHibernate.Driver.SqlClientDriver";
            cfg.SetProperty(NHibernate.Cfg.Environment.ConnectionString, config.Attributes[connectionStringKey]);// "ConnectionString
            cfg.SetProperty(NHibernate.Cfg.Environment.Dialect, GetDialect(config));// "ConnectionString
            //IApplication application = ComponentRegistry.Resolve<IApplication>();
            //if (application is IWebApplication)
            //{
            //    cfg.SetProperty("current_session_context_class", "web");
            //}
            //TODO：bytecode.provider
            //重写BytecodeProviderImpl.CreateInstance。通过IOC获取Domain。特别对于SAAS应用来说，尤其重要
            //cfg.SetProperty("proxyfactory.factory_class", typeof(ProxyFactoryFactory).FullName);
            //  cfg.SetProperty("default-lazy", "false");

            return cfg;
        }
        private string GetDriver(IConfiguration config)
        {
            EnumDescriptor databaseTypeDescriptor = EnumDescriptor.Get<DatabaseType>();
            DatabaseType dataBaseType = (DatabaseType)databaseTypeDescriptor.GetEnum(config.Attributes[databaseTypeKey]);
            switch (dataBaseType)
            {
                case DatabaseType.MsSql2008:
                case DatabaseType.MsSql2012:
                    return typeof(SqlClientDriver).FullName;
                case DatabaseType.MySQL5:
                    return typeof(MySqlDataDriver).FullName;
                default:
                    throw new NotSupportedException();
            }
        }
        private string GetDialect(IConfiguration config)
        {
            EnumDescriptor databaseTypeDescriptor = EnumDescriptor.Get<DatabaseType>();
            DatabaseType dataBaseType = (DatabaseType)databaseTypeDescriptor.GetEnum(config.Attributes[databaseTypeKey]);
            switch (dataBaseType)
            {
                case DatabaseType.MsSql2008:
                    return typeof(MsSql2008Dialect).FullName;
                case DatabaseType.MsSql2012:
                    return typeof(MsSql2012Dialect).FullName;
                case DatabaseType.MySQL5:
                    return typeof(MySQL5Dialect).FullName;
                default:
                    throw new NotSupportedException();
            }
        }
    }
}
